import datetime
import time
import json
from math import radians, sin, cos, asin, sqrt
from pyspark.sql.functions import udf
from pyspark.sql.window import Window
from pyspark.sql.types import IntegerType
from pyspark.sql.types import FloatType
from pyspark.sql.types import LongType
from pyspark.sql.types import TimestampType


### 数值转成datetime格式函数
@udf(returnType=TimestampType())
def intTodatetime(intValue):
    '''
    将int_value转化为 时间格式
    '''

    datetimeValue = datetime.datetime.now()
    if len(str(intValue)) == 10:
        # 精确到秒
        timeValue = time.localtime(intValue)
        tempDate = time.strftime("%Y-%m-%d %H:%M:%S", timeValue)
        datetimeValue = datetime.datetime.strptime(tempDate, "%Y-%m-%d %H:%M:%S")
    elif 10 < len(str(intValue)) and len(str(intValue)) < 15:
        # 精确到毫秒
        k = len(str(intValue)) - 10
        datetimeValue = datetime.datetime.fromtimestamp(intValue / (1 * 10 ** k))
        # datetimeValue = timetamp.strftime("%Y-%m-%d %H:%M:%S.%f")
    return datetimeValue


### 计算两个时间相差的秒数,默认返回10s
@udf(returnType=IntegerType())
def get_time_delta(t1, t2):
    try:
        return (t2 - t1).seconds
    except Exception as e:
        return 10


### 计算两点的距离
@udf(returnType=FloatType())
def geodistance(lng1, lat1, lng2, lat2):
    lng1, lat1, lng2, lat2 = map(radians, [lng1, lat1, lng2, lat2])
    dlon = lng2 - lng1
    dlat = lat2 - lat1
    a = sin(dlat / 2) ** 2 + cos(lat1) * cos(lat2) * sin(dlon / 2) ** 2
    dis = 2 * asin(sqrt(a)) * 6371 * 1000
    return dis


### 整数除法
@udf(returnType=LongType())
def integer_division(dividend):
    return dividend // 1000


### 计算电压
@udf(returnType=IntegerType())
def get_energy_storage_device_voltage(json_data):
    return json.loads(json_data)[''][0]['']

### 计算电流
@udf(returnType=IntegerType())
def get_energy_storage_device_current(json_data):
    return json.loads(json_data)[''][0]['']


### 计算探针温度值
@udf(returnType=FloatType())
def get_energy_storage_subsystem_temperature(json_data):
    return sum(json.loads(json_data)[''][0][
                   '']) / len(
        json.loads(json_data)[''][0][
            ''])


def error_calc(actual,pred):
    """
    误差计算方法
    """
    if actual == 0:
        if pred == 0:
            return 0
        else:
            return 1
    else:
        return min(abs(pred-actual)/actual,1)
